package com.ruoyi.movie.controller.app;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.movie.domain.MovieBasics;
import com.ruoyi.movie.domain.Actor;
import com.ruoyi.movie.domain.Cast;
import com.ruoyi.basic.domain.Column;
import com.ruoyi.movie.domain.MovieVideo;
import com.ruoyi.movie.domain.VideoResource;
import com.ruoyi.movie.service.IMovieBasicsService;
import com.ruoyi.movie.service.IActorService;
import com.ruoyi.movie.service.ICastService;
import com.ruoyi.basic.service.IColumnService;
import com.ruoyi.movie.service.IMovieVideoService;
import com.ruoyi.movie.service.IVideoResourceService;
import com.ruoyi.movie.mapper.MovieBasicsMapper;
import com.ruoyi.movie.mapper.MoviePvMapper;

import javax.annotation.Resource;

/**
 * App端影视模块Controller
 *
 * @author ruoyi
 * @date 2025-01-05
 */
@RestController
@RequestMapping("/app/movieapp")
public class MovieAppController extends BaseController
{
    @Autowired
    private IMovieBasicsService movieBasicsService;

    @Autowired
    private IActorService actorService;

    @Autowired
    private ICastService castService;

    @Autowired
    private IColumnService columnService;

    @Autowired
    private IMovieVideoService movieVideoService;

    @Autowired
    private IVideoResourceService videoResourceService;

    @Resource
    private MovieBasicsMapper movieBasicsMapper;

    @Resource
    private MoviePvMapper moviePvMapper;

    @Autowired
    private RedisCache redisCache;

    // 缓存key前缀
    private static final String HOT_MOVIE_KEY = "movie:hot:";
    private static final String NEW_MOVIE_KEY = "movie:new:";
    private static final String RECOMMEND_MOVIE_KEY = "movie:recommend:";
    private static final String HOME_MOVIE_KEY = "movie:home:";
    private static final String LIST_CACHE_KEY = "movie:list:";
    // 缓存时间配置（Integer类型）
    private static final Integer HOT_CACHE_TTL = 3600; // 1小时
    private static final Integer NEW_CACHE_TTL = 3600; // 1小时
    private static final Integer RECOMMEND_CACHE_TTL = 1800; // 30分钟（推荐要更随机）
    private static final Integer HOME_CACHE_TTL = 21600; // 6小时（首页缓存）
    private static final Integer LIST_CACHE_TTL = 21600; // 6小时（列表类型查询缓存）

    /**
     * 获取影视列表（分页，去重版本）
     * 只根据类型查询时使用6小时缓存，加快首页加载速度
     * @param movieBasics 栏目类型：movie/tv/cartoon/variety
     */
    @GetMapping("/list")
    public TableDataInfo list(MovieBasics movieBasics)
    {
        startPage();
        // 只返回正常状态的影视，使用去重查询
        movieBasics.setStatus("0");

        // 判断是否为纯类型查询（只有columnValue && tags参数，用于首页展示）
        boolean isPureColumnQuery = isOnlyColumnValueQuery(movieBasics);

        if (isPureColumnQuery && movieBasics.getSearchValue() != null) {
            String cacheKey = null;
            // 构建缓存key（包含类型和分页信息）
            com.github.pagehelper.Page page = (com.github.pagehelper.Page) com.github.pagehelper.PageHelper.getLocalPage();
            int pageNum = page != null ? page.getPageNum() : 1;
            int pageSize = page != null ? page.getPageSize() : 10;
            if("ALL".equals(movieBasics.getSearchValue())){
                cacheKey= LIST_CACHE_KEY + movieBasics.getColumnValue() + ":" + pageNum + ":" + pageSize;
            }else{
                if(StringUtils.isNotEmpty(movieBasics.getColumnValue())){
                    cacheKey= LIST_CACHE_KEY +movieBasics.getSearchValue()+"-"+ movieBasics.getColumnValue() + ":" + pageNum + ":" + pageSize;

                }else{
                    cacheKey= LIST_CACHE_KEY +movieBasics.getSearchValue() + ":" + pageNum + ":" + pageSize;

                }
            }
            // 尝试从缓存获取
            TableDataInfo cachedData = redisCache.getCacheObject(cacheKey);
            if (cachedData != null&& cachedData.getRows().size() > 0) {
                return cachedData;
            }
            if("ALL".equals(movieBasics.getSearchValue())){
                movieBasics.setSearchValue(null);
            }
            // 缓存未命中，查询数据库
            List<MovieBasics> list = movieBasicsService.selectMovieBasicsListDistinct(movieBasics);
            TableDataInfo dataInfo = getDataTable(list);

            // 存入缓存（6小时）
            redisCache.setCacheObject(cacheKey, dataInfo, LIST_CACHE_TTL, TimeUnit.SECONDS);
            return dataInfo;
        }

        // 非纯类型查询（带其他条件），不使用缓存
        List<MovieBasics> list = movieBasicsService.selectMovieBasicsListDistinct(movieBasics);
        return getDataTable(list);
    }

    /**
     * 判断是否为纯类型查询（只有columnValue，其他查询字段都为空）
     */
    private boolean isOnlyColumnValueQuery(MovieBasics movieBasics) {
        return movieBasics.getTitle() == null
            && movieBasics.getYear() == null
            && movieBasics.getIsPay() == null
            && movieBasics.getTheEnd() == null
                && movieBasics.getArea() == null
         && movieBasics.getTags() == null;
    }

    /**
     * 获取影视详情（包含按采集源分组的播放列表）
     */
    @GetMapping("/{movieBasicsId}")
    public AjaxResult getMovie(@PathVariable Integer movieBasicsId)
    {
        MovieBasics movie = movieBasicsService.selectMovieBasicsById(movieBasicsId);
        if (movie == null || !"0".equals(movie.getStatus())) {
            return error("影视不存在");
        }

        // 查询该影视的所有视频资源（包含播放器信息）
        List<VideoResource> allResources = videoResourceService.selectVideoResourceListByMovieId(movieBasicsId);

        // 按 play_from (播放器标识) 分组
        // 每个播放器对应一个播放来源，播放器自动跟随来源切换
        Map<String, Map<String, Object>> playListMap = new LinkedHashMap<>();

        for (VideoResource resource : allResources) {
            String playFrom = resource.getPlayFrom();
            if (playFrom == null || playFrom.isEmpty()) {
                playFrom = "default";
            }

            // 获取或创建该播放器的分组
            if (!playListMap.containsKey(playFrom)) {
                Map<String, Object> group = new HashMap<>();
                group.put("playFrom", playFrom);
                group.put("player", resource.getPlayer());  // 播放器配置（自动关联查询）
                group.put("playNote", resource.getPlayNote());  // 播放器备注/显示名称
                group.put("urls", new ArrayList<VideoResource>());
                playListMap.put(playFrom, group);
            }

            // 将资源添加到对应分组
            @SuppressWarnings("unchecked")
            List<VideoResource> urls = (List<VideoResource>) playListMap.get(playFrom).get("urls");
            urls.add(resource);
        }

        // 转换为List（保持顺序）
        List<Map<String, Object>> playList = new ArrayList<>(playListMap.values());

        // 构建返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("movie", movie);
        result.put("playList", playList);  // 播放列表（按播放器分组）

        return success(result);
    }

    /**
     * 搜索影视（增强版：支持多字段搜索+去重）
     * 支持按片名、演员、导演、编剧、简介搜索
     * 自动去重（相同片名+年份只显示一条）
     *
     * @param keyword 搜索关键词
     * @param columnValue 栏目值（可选，用于分类筛选）
     * @return 搜索结果
     */
    @GetMapping("/search")
    public TableDataInfo search(@RequestParam String keyword,
                                 @RequestParam(required = false) String columnValue)
    {
        if (StringUtils.isBlank(keyword)) {
            return getDataTable(new ArrayList<>());
        }

        startPage();
        // 使用新的多字段搜索方法（去重）
        List<MovieBasics> list = movieBasicsMapper.searchMoviesDistinct(
            keyword.trim(),
            columnValue,
            "0"  // 只返回正常状态的影视
        );
        return getDataTable(list);
    }

    /**
     * 获取推荐影视（随机推荐）
     */
    @GetMapping("/recommend")
    public TableDataInfo getRecommend(@RequestParam(required = false) String columnValue)
    {
        // 构建缓存key
        String cacheKey = RECOMMEND_MOVIE_KEY + (columnValue != null ? columnValue : "all");

        // 尝试从缓存获取
        TableDataInfo cachedData = redisCache.getCacheObject(cacheKey);
        if (cachedData != null) {
            return cachedData;
        }

        // 缓存未命中，查询数据库
        startPage();
        MovieBasics query = new MovieBasics();
        query.setStatus("0");
        if (columnValue != null && !columnValue.isEmpty()) {
            query.setColumnValue(columnValue);
        }
        List<MovieBasics> list = movieBasicsMapper.selectRecommendMovieList(query);
        TableDataInfo dataInfo = getDataTable(list);

        // 存入缓存（推荐时间短一些，保证随机性）
        redisCache.setCacheObject(cacheKey, dataInfo, RECOMMEND_CACHE_TTL, TimeUnit.SECONDS);
        return dataInfo;
    }

    /**
     * 获取首页推荐影视（去重版本，按pub_date排序，12小时缓存）
     * 用于首页展示，按最近发行日期排序
     */
    @GetMapping("/home")
    public AjaxResult getHomeRecommend(@RequestParam(required = false) String columnValue,
                                       @RequestParam(defaultValue = "12") Integer limit)
    {
        // 构建缓存key
        String cacheKey = HOME_MOVIE_KEY + (columnValue != null ? columnValue : "all") + ":" + limit;

        // 尝试从缓存获取
        List<MovieBasics> cachedList = redisCache.getCacheObject(cacheKey);
        if (cachedList != null) {
            return success(cachedList);
        }

        // 缓存未命中，查询数据库（去重 + pub_date排序）
        List<MovieBasics> list = movieBasicsService.selectHomeRecommendMovies(columnValue, limit);

        // 存入缓存（12小时）
        redisCache.setCacheObject(cacheKey, list, HOME_CACHE_TTL, TimeUnit.SECONDS);
        return success(list);
    }

    /**
     * 获取热门影视（按访问量排序）
     */
    @GetMapping("/hot")
    public TableDataInfo getHot(@RequestParam(required = false) String columnValue)
    {
        // 构建缓存key
        String cacheKey = HOT_MOVIE_KEY + (columnValue != null ? columnValue : "all");

        // 尝试从缓存获取
        TableDataInfo cachedData = redisCache.getCacheObject(cacheKey);
        if (cachedData != null) {
            return cachedData;
        }

        // 缓存未命中，查询数据库
        startPage();
        MovieBasics query = new MovieBasics();
        query.setStatus("0");
        if (columnValue != null && !columnValue.isEmpty()) {
            query.setColumnValue(columnValue);
        }
        List<MovieBasics> list = movieBasicsMapper.selectHotMovieList(query);
        TableDataInfo dataInfo = getDataTable(list);

        // 存入缓存
        redisCache.setCacheObject(cacheKey, dataInfo, HOT_CACHE_TTL, TimeUnit.SECONDS);
        return dataInfo;
    }

    /**
     * 获取最新影视（按发布日期排序）
     */
    @GetMapping("/new")
    public TableDataInfo getNew(@RequestParam(required = false) String columnValue)
    {
        // 构建缓存key
        String cacheKey = NEW_MOVIE_KEY + (columnValue != null ? columnValue : "all");

        // 尝试从缓存获取
        TableDataInfo cachedData = redisCache.getCacheObject(cacheKey);
        if (cachedData != null) {
            return cachedData;
        }

        // 缓存未命中，查询数据库
        startPage();
        MovieBasics query = new MovieBasics();
        query.setStatus("0");
        if (columnValue != null && !columnValue.isEmpty()) {
            query.setColumnValue(columnValue);
        }
        List<MovieBasics> list = movieBasicsMapper.selectNewMovieList(query);
        TableDataInfo dataInfo = getDataTable(list);

        // 存入缓存
        redisCache.setCacheObject(cacheKey, dataInfo, NEW_CACHE_TTL, TimeUnit.SECONDS);
        return dataInfo;
    }

    /**
     * 根据栏目获取影视列表
     */
    @GetMapping("/column/{columnValue}")
    public TableDataInfo getByColumn(@PathVariable String columnValue)
    {
        startPage();
        MovieBasics query = new MovieBasics();
        query.setColumnValue(columnValue);
        query.setStatus("0");
        List<MovieBasics> list = movieBasicsService.selectMovieBasicsList(query);
        return getDataTable(list);
    }

    /**
     * 获取影视的栏目标签
     */
    @GetMapping("/{movieBasicsId}/columns")
    public AjaxResult getMovieColumns(@PathVariable Integer movieBasicsId)
    {
        MovieBasics movie = movieBasicsService.selectMovieBasicsById(movieBasicsId);
        if (movie != null && movie.getColumns() != null) {
            return success(movie.getColumns());
        }
        return success(new ArrayList<>());
    }

    /**
     * 获取影视的演职人员
     */
    @GetMapping("/{movieBasicsId}/casts")
    public AjaxResult getMovieCasts(@PathVariable Integer movieBasicsId)
    {
        Cast query = new Cast();
        query.setMovieId(movieBasicsId);
        List<Cast> list = castService.selectCastList(query);
        return success(list);
    }

    /**
     * 获取影视的视频列表（剧集/预告片等）
     */
    @GetMapping("/{movieBasicsId}/videos")
    public AjaxResult getMovieVideos(@PathVariable Integer movieBasicsId)
    {
        MovieVideo query = new MovieVideo();
        query.setMovieId(movieBasicsId);
        List<MovieVideo> list = movieVideoService.selectMovieVideoList(query);
        return success(list);
    }

    /**
     * 获取视频资源（播放地址）
     */
    @GetMapping("/video/{movieVideoId}/resources")
    public AjaxResult getVideoResources(@PathVariable Long movieVideoId)
    {
        List<VideoResource> list = videoResourceService.selectVideoResourceByVideoId(movieVideoId);
        return success(list);
    }

    /**
     * 增加影视播放量
     */
    @PostMapping("/{movieBasicsId}/play")
    public AjaxResult increasePlayCount(@PathVariable Integer movieBasicsId)
    {
        MovieBasics movie = movieBasicsService.selectMovieBasicsById(movieBasicsId);
        if (movie != null) {
            // 增加播放量统计
            try {
                moviePvMapper.increaseMoviePv(movieBasicsId);
                return success("播放量已增加");
            } catch (Exception e) {
                logger.error("增加播放量失败", e);
                // 即使失败也返回成功，不影响用户播放
                return success();
            }
        }
        return error("影视不存在");
    }

    /**
     * 获取演员详情
     */
    @GetMapping("/actor/{actorId}")
    public AjaxResult getActor(@PathVariable Long actorId)
    {
        return success(actorService.selectActorByActorId(actorId));
    }

    /**
     * 获取演员作品列表
     */
    @GetMapping("/actor/{actorId}/movies")
    public TableDataInfo getActorMovies(@PathVariable Integer actorId)
    {
        startPage();
        // 查询该演员参演的所有角色
        Cast query = new Cast();
        query.setActorId(actorId);
        List<Cast> castList = castService.selectCastList(query);

        // 提取影视ID列表
        List<Integer> movieIds = castList.stream()
                .map(Cast::getMovieId)
                .distinct()
                .collect(Collectors.toList());

        // 查询影视详情
        if (movieIds.isEmpty()) {
            return getDataTable(new ArrayList<>());
        }

        // 根据影视ID列表查询影视详情
        List<MovieBasics> movies = movieIds.stream()
                .map(movieId -> movieBasicsService.selectMovieBasicsById(movieId))
                .filter(movie -> movie != null && "0".equals(movie.getStatus()))
                .collect(Collectors.toList());

        return getDataTable(movies);
    }

    /**
     * 获取所有栏目类型
     */
    @GetMapping("/columns")
    public AjaxResult getColumns(@RequestParam(required = false) String type)
    {
        Column query = new Column();
        query.setStatus("0");
        if (type != null && !type.isEmpty()) {
            query.setType(type);
        }
        List<Column> list = columnService.selectColumnList(query);
        return success(list);
    }

    /**
     * 获取筛选条件选项（动态加载）
     * @param columnValue 栏目类型
     */
    @GetMapping("/filter-options")
    public AjaxResult getFilterOptions(@RequestParam(required = false) String columnValue)
    {
        Map<String, Object> options = new HashMap<>();

        // 获取标签/类型列表（从tags字段提取）
        List<Column> tags = columnService.selectDistinctTags(columnValue);
        options.put("tags", tags);

        // 获取年份列表
        List<Integer> years = movieBasicsService.selectDistinctYears(columnValue);
        options.put("years", years);

        // 获取地区列表（从area字段提取）
        List<String> areas = movieBasicsService.selectDistinctAreas(columnValue);
        options.put("areas", areas);

        return success(options);
    }
}
